home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 07 - 1991 / 07.12 Dec 91 / MacSocket Code / MacSocket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-18  |  22.5 KB  |  1,066 lines  |  [TEXT/KAHL]

  1. /***
  2.  *** Copyright (c) 1990 Rijksinstituut voor Visserijonderzoek, IJmuiden.
  3.  *** All rights reserved.
  4.  ***
  5.  *** Redistribution and use in source and binary forms are permitted
  6.  *** provided that this notice is preserved and that due credit is given
  7.  *** to the Rijksinstituut voor Visserijonderzoek at IJmuiden.
  8.  *** This software is provided "as is" without express or implied warranty.
  9.  ***
  10.  *** @(#)MacSocket.c 1.7 91/04/04
  11.  ***/
  12.  
  13. /*
  14. #define    MAC_APPL
  15. */
  16. #include    "MacSocket.h"
  17.  
  18. #define    Connected        (0x01)
  19.  
  20. typedef struct SockElmnt
  21. {
  22.     int                    number;
  23.     struct SockElmnt    *next;
  24.     int                    state;
  25.     TCPiopb                thePB;
  26.     char                sockBuf[SockBufSize];
  27. } SockElmnt, *SockElmntPtr, **SockElmntHdl;
  28.  
  29. #ifdef    MAC_APPL
  30.  
  31. #define    LineLength        (350)
  32. #define    AMargin            (13)
  33. #define    BMargin            (23)
  34. #define    IconSize        (32)
  35. #define    DlogTop            (66)
  36. #define    DlogLeft        (50)
  37. #define    ButtonHeight    (22)
  38. #define ButtonLength    (59)
  39.  
  40. typedef struct AlertDitl
  41. {
  42.     unsigned short    nItems;
  43.     Handle            textHandle;
  44.     Rect            textRect;
  45.     unsigned char    text;
  46.     unsigned char    textSize;
  47.     char            textString[8];
  48.     Handle            buttonHandle;
  49.     Rect            buttonRect;
  50.     unsigned char    button;
  51.     unsigned char    buttonSize;
  52.     char            buttonString[2];
  53.     Handle            iconHandle;
  54.     Rect            iconRect;
  55.     unsigned char    icon;
  56.     unsigned char    iconSize;
  57.     unsigned short    iconId;
  58.     Handle            outlineHandle;
  59.     Rect            outlineRect;
  60.     unsigned char    outline;
  61.     unsigned char    outlineSize;
  62. } AlertDitl, *AlertDitlPtr, **AlertDitlHdl;
  63.  
  64. #endif    MAC_APPL
  65.  
  66. #ifdef    close
  67. #undef    close
  68. #endif    close
  69.  
  70. #ifdef    exit
  71. #undef    exit
  72. #ifdef    MAC_APPL
  73. #define    exit(s)    ExitToShell()
  74. #endif    MAC_APPL
  75. #endif    exit
  76.  
  77. #ifdef    perror
  78. #undef    perror
  79. #endif    perror
  80.  
  81. #ifdef    strerror
  82. #undef    strerror
  83. #endif    strerror
  84.  
  85. /**
  86.  **
  87.  ** local prototypes
  88.  **
  89.  **/
  90. static    void            DoAlert(int alertId, char* s1, char* s2, char* s3, char* s4);
  91. static    SockElmntPtr    CreateSocketStruct(void);
  92. static    SockElmntPtr    FindSocketStruct(int);
  93. static    int                OpenTCPDriver(void);
  94. static    pascal    void    OutlineProc(DialogPtr thePtr, int theItem);
  95. static    void            PollTCPDriver(TCPiopb *thePB);
  96. static    int                RemoveSocketStruct(int);
  97. static    pascal    void    SockNotify(StreamPtr tcpStream,
  98.                             unsigned short eventCode,
  99.                             Ptr userDataPtr,
  100.                             unsigned short terminReason,
  101.                             struct ICMPReport *icmpMsg);
  102.  
  103.  
  104. /**
  105.  **
  106.  ** local variables
  107.  **
  108.  **/
  109. static    int                errno_MacSocket = noErr;
  110. static    int                ioRefNumTCP;
  111. static    char            macSocketErrorMssg[128] = "no error!";
  112. static    int                showTime = 4;
  113. static    int                sockNumber = 4;
  114. static    SockElmntPtr    theHeadPtr = NIL;
  115. static    char            TCPDriverName[] = "\p.IPP";
  116. static    char            theUserData[UserDataSize];
  117. static    char            TCPDriverNotOpened = True;
  118.  
  119. #ifdef    LAB_VIEW
  120.  
  121. static    SockElmnt        theSockElmnt;
  122.  
  123. #endif    LAB_VIEW
  124.  
  125. /***
  126.  ***
  127.  *** Mac versions the standard Socket-based internet communication protocol:
  128.  ***
  129.  ***/
  130.  
  131. /**
  132.  **
  133.  ** Local functions
  134.  **
  135.  **/
  136.  
  137. /*
  138.  *
  139.  * CreateSocketStruct - creates a data structure for a particular socket into a
  140.  * linked list
  141.  *
  142.  */
  143. static    SockElmntPtr    CreateSocketStruct()
  144. {
  145.     register    SockElmntPtr    theSockPtr;
  146.     
  147.     if ((theSockPtr = (SockElmntPtr)malloc(SizeOf(SockElmnt))) == NIL)
  148.     {
  149.         errno_MacSocket = noBufSpace;
  150.         return (NIL);
  151.     }
  152.     theSockPtr->next = theHeadPtr;
  153.     theSockPtr->state = 0x00;
  154.     theHeadPtr = theSockPtr;
  155.     theSockPtr->number = ++sockNumber;
  156.     return (theSockPtr);
  157. }
  158.  
  159. #ifdef    MAC_APPL
  160. /*
  161.  *
  162.  * DoAlert - shows an alert message on the screen. When alertId is negative,
  163.  * no icon and OK-button are displayed. The Alert message is then "showTime"
  164.  * seconds visible.
  165.  *
  166.  */
  167. static void DoAlert(int alertId, char* s1, char* s2, char* s3, char* s4)
  168. {
  169.     AlertDitlPtr    theAlertDitlPtr;
  170.     AlertDitlHdl    theAlertDitlHdl;
  171.     DialogRecord    dlogRecord;
  172.     DialogPtr        theDlogPtr;
  173.     Rect            theBounds;
  174.     int                theItem;
  175.     int                textHeight;
  176.     int                nChars;
  177.     FontInfo        theFont;
  178.     
  179.     if ((alertId < 0) && (showTime <= 0))
  180.     {
  181.         return;
  182.     }
  183.     
  184.     theAlertDitlHdl = (AlertDitlHdl)NewHandle(sizeof(AlertDitl));
  185.     if (theAlertDitlHdl != NIL)
  186.     {
  187.         HLock(theAlertDitlHdl);
  188.         theAlertDitlPtr = * theAlertDitlHdl;
  189.         
  190.         nChars = (int)((unsigned char)*s1) +
  191.             (int)((unsigned char)*s2) +
  192.             (int)((unsigned char)*s3) +
  193.             (int)((unsigned char)*s4);
  194.     
  195.         GetFontInfo(&theFont);
  196.         textHeight = ((nChars * theFont.widMax) / LineLength + 1) *
  197.             (theFont.ascent + theFont.descent + theFont.leading);
  198.         if ((textHeight < IconSize) && (alertId >= 0))
  199.         {
  200.             textHeight = IconSize;
  201.         }
  202.     
  203.         theAlertDitlPtr->nItems = (alertId >= 0) ? 3 : 0;
  204.     
  205.         theAlertDitlPtr->textHandle = ((void*) 0L);
  206.         theAlertDitlPtr->textRect.top = AMargin - 3;
  207.         theAlertDitlPtr->textRect.left = BMargin - 3;
  208.         if (alertId >= 0)
  209.         {
  210.             theAlertDitlPtr->textRect.left += IconSize + BMargin;
  211.         }
  212.         theAlertDitlPtr->textRect.bottom =
  213.             theAlertDitlPtr->textRect.top + textHeight;
  214.         theAlertDitlPtr->textRect.right =
  215.             theAlertDitlPtr->textRect.left + LineLength;
  216.         theAlertDitlPtr->text = statText + itemDisable;
  217.         theAlertDitlPtr->textSize = 8;
  218.         theAlertDitlPtr->textString[0] = '^';
  219.         theAlertDitlPtr->textString[1] = '0';
  220.         theAlertDitlPtr->textString[2] = '^';
  221.         theAlertDitlPtr->textString[3] = '1';
  222.         theAlertDitlPtr->textString[4] = '^';
  223.         theAlertDitlPtr->textString[5] = '2';
  224.         theAlertDitlPtr->textString[6] = '^';
  225.         theAlertDitlPtr->textString[7] = '3';
  226.     
  227.         if (alertId >= 0)
  228.         {
  229.             theAlertDitlPtr->buttonHandle = ((void*) 0L);
  230.             theAlertDitlPtr->buttonRect.top =
  231.                 theAlertDitlPtr->textRect.bottom + AMargin;
  232.             theAlertDitlPtr->buttonRect.right =
  233.                 theAlertDitlPtr->textRect.right;
  234.             theAlertDitlPtr->buttonRect.bottom =
  235.                 theAlertDitlPtr->buttonRect.top + ButtonHeight;
  236.             theAlertDitlPtr->buttonRect.left =
  237.                 theAlertDitlPtr->buttonRect.right - ButtonLength;
  238.             theAlertDitlPtr->button = ctrlItem + btnCtrl;
  239.             theAlertDitlPtr->buttonSize = 2;
  240.             theAlertDitlPtr->buttonString[0] = 'O';
  241.             theAlertDitlPtr->buttonString[1] = 'K';
  242.         
  243.             theAlertDitlPtr->iconHandle = ((void*) 0L);
  244.             theAlertDitlPtr->iconRect.top = theAlertDitlPtr->textRect.top;
  245.             theAlertDitlPtr->iconRect.left = BMargin - 3;
  246.             theAlertDitlPtr->iconRect.bottom =
  247.                 theAlertDitlPtr->iconRect.top + IconSize;
  248.             theAlertDitlPtr->iconRect.right =
  249.                 theAlertDitlPtr->iconRect.left + IconSize;
  250.             theAlertDitlPtr->icon = iconItem + itemDisable;
  251.             theAlertDitlPtr->iconSize = 2;
  252.             theAlertDitlPtr->iconId = alertId;
  253.         
  254.             theAlertDitlPtr->outlineHandle = (Handle)&OutlineProc;
  255.             theAlertDitlPtr->outlineRect.top = theAlertDitlPtr->buttonRect.top;
  256.             theAlertDitlPtr->outlineRect.left = theAlertDitlPtr->buttonRect.left;
  257.             theAlertDitlPtr->outlineRect.bottom = theAlertDitlPtr->buttonRect.bottom;
  258.             theAlertDitlPtr->outlineRect.right = theAlertDitlPtr->buttonRect.right;
  259.             theAlertDitlPtr->outline = userItem + itemDisable;
  260.             theAlertDitlPtr->outlineSize = 0;
  261.         }
  262.     
  263.         theBounds.top = DlogTop;
  264.         theBounds.left = DlogLeft;
  265.         theBounds.bottom = DlogTop + AMargin - 3;
  266.         theBounds.bottom += (alertId >= 0) ?
  267.             theAlertDitlPtr->buttonRect.bottom :
  268.             theAlertDitlPtr->textRect.bottom;
  269.         theBounds.right = DlogLeft + theAlertDitlPtr->textRect.right + AMargin - 3;
  270.     
  271.         HUnlock(theAlertDitlHdl);
  272.         
  273.         ParamText(s1, s2, s3, s4);
  274.         theDlogPtr = NewDialog(&dlogRecord, &theBounds, "\p", True, dBoxProc,
  275.             InFrontOfAll, False, 0L, theAlertDitlHdl);
  276.         if (alertId >= 0)
  277.         {
  278.             ModalDialog(NIL, &theItem);
  279.         }
  280.         else
  281.         {
  282.             DrawDialog(theDlogPtr);
  283.             sleep(showTime);
  284.         }
  285.         CloseDialog(theDlogPtr);
  286.         DisposHandle(theAlertDitlHdl);
  287.     }
  288. };
  289. #endif MAC_APPL
  290.  
  291. /*
  292.  *
  293.  * FindSocketStruct - finds a data structure for a particular socket in a linked list
  294.  *
  295.  */
  296. static SockElmntPtr    FindSocketStruct(int sock)
  297. {
  298.     register    SockElmntPtr    theSockPtr;
  299.  
  300.     for (theSockPtr = theHeadPtr; theSockPtr != NIL;
  301.       theSockPtr = (SockElmntPtr)theSockPtr->next)
  302.     {
  303.         if (theSockPtr->number == sock)
  304.         {
  305.             errno_MacSocket = noErr;
  306.             return (theSockPtr);
  307.         }
  308.     }
  309.     errno_MacSocket = nonSocket;
  310.     return (NIL);
  311. }
  312.  
  313. /*
  314.  *
  315.  * OpenTCPDriver - loads and opens UDP-TCP/IP driver (".IPP")
  316.  *
  317.  */
  318. static    int    OpenTCPDriver()
  319. {
  320.     ParamBlockRec    thePB;
  321.     
  322.     thePB.ioParam.ioCompletion = NIL;
  323.     thePB.ioParam.ioNamePtr = (StringPtr)TCPDriverName;
  324.     thePB.ioParam.ioPermssn = fsCurPerm;
  325.     PBOpen(&thePB, Asynchronous);
  326.     PollTCPDriver((TCPiopb *)&thePB);
  327.     if (errno_MacSocket == noErr)
  328.     {
  329.         TCPDriverNotOpened = False;
  330.         ioRefNumTCP = thePB.ioParam.ioRefNum;
  331.         return(1);
  332.     }
  333.     else
  334.     {
  335.         errno_MacSocket = noTCPDriver;
  336.         return(0);
  337.     }
  338. }
  339.  
  340. #ifdef MAC_APPL
  341. /*
  342.  *
  343.  * OutlineProc - Outlines an item in a dialogbox
  344.  *
  345.  */
  346. static pascal void OutlineProc(WindowPtr thePtr, int theItem)
  347. {
  348.     int        theItemType;
  349.     GrafPtr    currentPort;
  350.     Handle    theItemHdl;
  351.     Rect    theBox;
  352.  
  353.     GetDItem (thePtr, theItem, &theItemType, &theItemHdl, &theBox);
  354.     GetPort(¤tPort);
  355.     SetPort(thePtr);
  356.     PenSize(3, 3);
  357.     InsetRect(&theBox, -4, -4);
  358.     FrameRoundRect (&theBox, 16, 16);
  359.     PenNormal();
  360.     SetPort(currentPort);
  361. };
  362. #endif    MAC_APPL
  363.  
  364. /*
  365.  *
  366.  * PollTCPDriver - polls the UDP-TCP/IP driver until an action is completed
  367.  *
  368.  */
  369. static    void    PollTCPDriver(TCPiopb *theTCPPtr)
  370. {
  371.     while((errno_MacSocket = theTCPPtr->ioResult) > 0)
  372.     {
  373.         SystemTask();
  374.     }
  375. }
  376.  
  377. /*
  378.  *
  379.  * RemoveSocketStruct - removes a data structure for a particular socket from a
  380.  * linked list
  381.  *
  382.  */
  383. static int    RemoveSocketStruct(int sock)
  384. {
  385.     register    SockElmntPtr    theSockPtr, thePrevOne = NIL;
  386.  
  387.     for (theSockPtr = theHeadPtr; theSockPtr != NIL;
  388.       thePrevOne = theSockPtr, theSockPtr = (SockElmntPtr)theSockPtr->next)
  389.     {
  390.         if (theSockPtr->number == sock)
  391.         {
  392.             if (thePrevOne == NIL)
  393.             {
  394.                 theHeadPtr = theSockPtr->next;
  395.             }
  396.             else
  397.             {
  398.                 thePrevOne->next = theSockPtr->next;
  399.             }
  400.             free(theSockPtr);
  401.             errno_MacSocket = noErr;
  402.             return (1);
  403.         }
  404.     }
  405.     errno_MacSocket = nonSocket;
  406.     return(0);
  407. }
  408.  
  409. /*
  410.  *
  411.  * SockNotify - prints notification messages for the UDP-TCP/IP driver
  412.  *
  413.  */
  414. static pascal void SockNotify(StreamPtr tcpStream, unsigned short eventCode,
  415.   Ptr userDataPtr, unsigned short terminReason, struct ICMPReport *icmpMsg)
  416. {
  417.     char    theErrorMsg[128];
  418.     char    *errStrPtr1 = "\0", *errStrPtr2 = "\0";
  419. #ifdef    MAC_APPL
  420.     char    errNoStr[32];
  421. #endif    MAC_APPL
  422.     
  423.     strcpy(theErrorMsg, "MacSocket: ");
  424.     switch (eventCode)
  425.     {
  426.     case TCPClosing:
  427.         errStrPtr1 = "all data has been received and delivered";
  428.         break;
  429.     case TCPULPTimeout:
  430.         errStrPtr1 = "time out";
  431.         break;
  432.     case TCPTerminate:
  433.         errStrPtr1 = "connection terminated, ";
  434.         switch(terminReason)
  435.         {
  436.         case TCPRemoteAbort:
  437.             errStrPtr2 = "connection reset by peer";
  438.             break;
  439.         case TCPNetworkFailure:
  440.             errStrPtr2 = "network failure";
  441.             break;
  442.         case TCPSecPrecMismatch:
  443.             errStrPtr2 = "invallid security option or precedence level";
  444.             break;
  445.         case TCPULPTimeoutTerminate:
  446.             errStrPtr2 = "ULP time out";
  447.             break;
  448.         case TCPULPAbort:
  449.             errStrPtr2 = "connection aborted";
  450.             break;
  451.         case TCPULPClose:
  452.             errStrPtr2 = "connection closed gracefully";
  453.             break;
  454.         case TCPServiceError:
  455.             errStrPtr2 = "unexpected connection initiation segment read";
  456.             break;
  457.         default:
  458.             errStrPtr2 = "unknown reason";
  459.             break;
  460.         }
  461.         break;
  462.     case TCPDataArrival:
  463.         errStrPtr1 = "data arrived, no receive outstanding";
  464.         break;
  465.     case TCPUrgent:
  466.         errStrPtr1 = "urgent data arrived";
  467.         break;
  468.     case TCPICMPReceived:
  469.         errStrPtr1 = "Internet Control Message arrived";
  470.         /* still to be printed */
  471.         break;
  472.     default:
  473.         errStrPtr1 = "unknown eventcode";
  474.         break;
  475.     }
  476.     strcat(theErrorMsg, errStrPtr1);
  477.     strcat(theErrorMsg, errStrPtr2);
  478. #ifndef    MAC_APPL
  479.     fprintf(stderr, "%s (%d).\n", theErrorMsg, eventCode);
  480. #else    MAC_APPL
  481.     NumToString(eventCode, errNoStr);
  482.     DoAlert(-1, CtoPstr(theErrorMsg), "\p(", errNoStr, "\p)");
  483. #endif    MAC_APPL
  484. };
  485.  
  486. /**
  487.  **
  488.  ** Global functions
  489.  **
  490.  **/
  491.  
  492. /**
  493.  **
  494.  ** Functions that substitute relevant UNIX-system calls on the Mac
  495.  **
  496.  **/
  497.  
  498. /*
  499.  *
  500.  * close_MacSocket - delete a (socket) descriptor if present, else do close(int s)
  501.  *
  502.  */
  503. int close_MacSocket(int s)
  504. {
  505.     TCPiopb            *theTCPPtr;
  506.     SockElmntPtr    theSockPtr, thePrevPtr = NIL;
  507.  
  508.     if ((theSockPtr = FindSocketStruct(s)) == NIL)
  509.     {
  510.         return(close(s));
  511.     }
  512.     
  513.     theTCPPtr = &(theSockPtr->thePB);
  514.     theTCPPtr->csCode = TCPClose;
  515.     theTCPPtr->csParam.close.ulpTimeoutValue = CloseTimeout;
  516.     theTCPPtr->csParam.close.ulpTimeoutAction = Abort;
  517.     theTCPPtr->csParam.close.validityFlags = (byte)(timeoutValue | timeoutAction);
  518.     theTCPPtr->csParam.close.userDataPtr = (Ptr)&theUserData;
  519.     PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
  520.     PollTCPDriver(theTCPPtr);
  521.     theSockPtr->number = -1;
  522.     if (errno_MacSocket == noErr)
  523.     {
  524.         return(0);
  525.     }
  526.     else
  527.     {
  528.         return (-1);
  529.     }
  530. };
  531.  
  532. /*
  533.  *
  534.  * exit_MacSocket - substitute for exit(int status)
  535.  *
  536.  */
  537. void exit_MacSocket(int status)
  538. {
  539.     ParamBlockRec    thePB;
  540.  
  541.     while (theHeadPtr != NIL)
  542.     {
  543.         shutdown(theHeadPtr->number, 2);
  544.     }
  545.     
  546.     if (!TCPDriverNotOpened)
  547.     {
  548.         thePB.ioParam.ioCompletion = NIL;
  549.         thePB.ioParam.ioRefNum = ioRefNumTCP;
  550.         PBClose(&thePB, Asynchronous);
  551.         /*
  552.         PollTCPDriver(&thePB);
  553.         */
  554.     }
  555.     exit(status);
  556. }
  557.  
  558. /*
  559.  *
  560.  * perror_MacSocket - substitute for void perror(char *s)
  561.  *
  562.  */
  563. void perror_MacSocket(char *s)
  564. {
  565.     char    theErrorMsg[128];
  566. #ifdef    MAC_APPL
  567.     char    errNoStr[32];
  568. #endif    MAC_APPL
  569.     
  570.     strcpy(theErrorMsg, s);
  571.     strcat(theErrorMsg, ": ");
  572.     strcat(theErrorMsg, strerror_MacSocket(errno_MacSocket));
  573. #ifndef    MAC_APPL
  574.     fprintf(stderr, "%s (%d).\n", theErrorMsg, errno_MacSocket);
  575. #else    MAC_APPL
  576.     NumToString(errno_MacSocket, errNoStr);
  577.     DoAlert(stopIcon, CtoPstr(theErrorMsg), "\p (", errNoStr, "\p).");
  578. #endif    MAC_APPL
  579. }
  580.  
  581. /*
  582.  *
  583.  * strerror_MacSocket - substitute for strerror(int errnum)
  584.  *
  585.  */
  586. char*    strerror_MacSocket(int errnum)
  587. {
  588.     char    *errStrPtr;
  589.     
  590.     switch (errnum)
  591.     {
  592.     case noTCPDriver:
  593.         errStrPtr = "UDP-TCP/IP driver (\".IPP\") not available";
  594.         break;
  595.     case invalidArgument:
  596.         errStrPtr = "invalid address argument";
  597.         break;
  598.     case nonSOCK_STREAM:
  599.         errStrPtr = "socket type not supported";
  600.         break;
  601.     case nonSocket:
  602.         errStrPtr = "invalid socket descriptor";
  603.         break;
  604.     case nonAF_INET:
  605.         errStrPtr = "domain not supported";
  606.         break;
  607.     case noBufSpace:
  608.         errStrPtr = "no memory for buffers available";
  609.         break;
  610.     case ipBadLapErr:
  611.         errStrPtr = "bad network configuration";
  612.         break;
  613.     case ipBadCnfgErr:
  614.         errStrPtr = "bad IP configuration error";
  615.         break;
  616.     case ipNoCnfgErr:
  617.         errStrPtr = "missing IP or LAP configuration error";
  618.         break;
  619.     case ipLoadErr:
  620.         errStrPtr = "error in MacTCP load";
  621.         break;
  622.     case ipBadAddr:
  623.         errStrPtr = "error in getting address";
  624.         break;
  625.     case streamAlreadyOpen:
  626.         errStrPtr = "an open stream is already using this receive buffer area";
  627.         break;
  628.     case invalidLength:
  629.         errStrPtr = "the buffer is too small or too large";
  630.         break;
  631.     case invalidBufPtr:
  632.         errStrPtr = "illegal buffer pointer";
  633.         break;
  634.     case insufficientResources:
  635.         errStrPtr = "there are already 64 TCP streams open";
  636.         break;
  637.     case invalidStreamPtr:
  638.         errStrPtr = "the specified TCP stream is not open";
  639.         break;
  640.     case connectionExists:
  641.         errStrPtr = "this TCP stream has an open connection";
  642.         break;
  643.     case duplicateSocket:
  644.         errStrPtr = "a connection already exists on this link";
  645.         break;
  646.     case commandTimeout:
  647.         errStrPtr = "no connection attempt was received in the specified time-out period";
  648.         break;
  649.     case openFailed:
  650.         errStrPtr = "the connection came halfway up and then failed";
  651.         break;
  652.     case connectionDoesntExist:
  653.         errStrPtr = "there is no open connection on this stream";
  654.         break;
  655.     case connectionClosing:
  656.         errStrPtr = "a TCP close command was already issued";
  657.         break;
  658.     case connectionTerminated:
  659.         errStrPtr = "the connection went down";
  660.         break;
  661.     case invalidRDS:
  662.         errStrPtr = "trying to release wrong buffer";
  663.         break;
  664.     default:
  665.         errStrPtr = strerror(errnum);;
  666.         break;
  667.     }
  668.     strcpy(macSocketErrorMssg, errStrPtr);
  669.     return(macSocketErrorMssg);
  670. }
  671.  
  672.  
  673. /**
  674.  **
  675.  ** MacSocket calls
  676.  **
  677.  **/
  678.  
  679. /*
  680.  *
  681.  * accept - accept a connection on a socket
  682.  *
  683.  */
  684. /*
  685. int accept(int s, struct sockaddr *addr, int addrlen)
  686. {
  687. };
  688. */
  689.  
  690. /*
  691.  *
  692.  * bind - bind a name to a socket
  693.  *
  694.  */
  695. /*
  696. int bind(int s, struct sockaddr *name, int namelen)
  697. {
  698. };
  699. */
  700.  
  701. /*
  702.  *
  703.  * connect - initiate a connection on a socket
  704.  *
  705.  */
  706. int connect(int s, struct sockaddr_in *name, int namelen)
  707. {
  708.     TCPiopb            *theTCPPtr;
  709.     SockElmntPtr    theSockPtr;
  710.     
  711.     if (namelen != sizeof(struct sockaddr_in))
  712.     {
  713.         errno_MacSocket = invalidArgument;
  714.         return (-1);
  715.     }
  716.  
  717.     if ((theSockPtr = FindSocketStruct(s)) == NIL)
  718.     {
  719.         errno_MacSocket = invalidStreamPtr;
  720.         return (-1);
  721.     }
  722.     
  723.     theTCPPtr = &(theSockPtr->thePB);
  724.     theTCPPtr->csCode = TCPActiveOpen;
  725.     theTCPPtr->csParam.open.ulpTimeoutValue = ConnectTimeout;
  726.     theTCPPtr->csParam.open.ulpTimeoutAction = Abort;
  727.     theTCPPtr->csParam.open.validityFlags =
  728.       (byte)(timeoutValue | timeoutAction | typeOfService | precedence);
  729.     memcpy((void *)&theTCPPtr->csParam.open.remoteHost, (void *)&name->sin_addr,
  730.         sizeof(name->sin_addr));
  731.     theTCPPtr->csParam.open.remotePort = name->sin_port;
  732.     theTCPPtr->csParam.open.localPort = 0;
  733.     theTCPPtr->csParam.open.tosFlags = (byte)(reliability | lowDelay);
  734.     theTCPPtr->csParam.open.precedence = 0;
  735.     theTCPPtr->csParam.open.dontFrag = False;
  736.     theTCPPtr->csParam.open.timeToLive = (byte)60;
  737.     theTCPPtr->csParam.open.security = False;
  738.     theTCPPtr->csParam.open.optionCnt = (byte)0;
  739.     theTCPPtr->csParam.open.userDataPtr = (Ptr)&theUserData;
  740.     PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
  741.     PollTCPDriver(theTCPPtr);
  742.     if (errno_MacSocket == noErr)
  743.     {
  744.         theSockPtr->state |= Connected;
  745.         return (0);
  746.     }
  747.     else
  748.     {
  749.         theSockPtr->state &= ~Connected;
  750.         return (-1);
  751.     }
  752. };
  753.  
  754. /*
  755.  *
  756.  * listen - listen for connections on a socket
  757.  *
  758.  */
  759. /*
  760. int listen(int s, int backlog)
  761. {
  762. };
  763. */
  764.  
  765. /*
  766.  *
  767.  * recv - receive a message from a socket
  768.  *
  769.  */
  770. int recv(int s, char *msg, int len, int flags)
  771. {
  772.     TCPiopb            *theTCPPtr;
  773.     SockElmntPtr    theSockPtr;
  774.     
  775.     if ((theSockPtr = FindSocketStruct(s)) == NIL)
  776.     {
  777.         errno_MacSocket = invalidStreamPtr;
  778.         return (-1);
  779.     }
  780.         
  781.     theTCPPtr = &(theSockPtr->thePB);
  782.     theTCPPtr->csCode = TCPRcv;
  783.     theTCPPtr->csParam.receive.commandTimeoutValue = RecvTimeout;
  784.     theTCPPtr->csParam.receive.rcvBuff = msg;
  785.     theTCPPtr->csParam.receive.rcvBuffLen = len;
  786.     theTCPPtr->csParam.receive.userDataPtr = (Ptr)&theUserData;
  787.     PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
  788.     PollTCPDriver(theTCPPtr);
  789.     if (errno_MacSocket == noErr)
  790.     {
  791.         return (theTCPPtr->csParam.receive.rcvBuffLen);
  792.     }
  793.     else
  794.     {
  795.         return (-1);
  796.     }
  797. };
  798.  
  799. /*
  800.  *
  801.  * recvfrom - receive a message from a socket
  802.  *
  803.  */
  804. int recvfrom(int s, char *msg, int len, int flags, struct sockaddr_in *from, int *fromlen)
  805. {
  806.     SockElmntPtr    theSockPtr;
  807.     
  808.     if ((theSockPtr = FindSocketStruct(s)) == NIL)
  809.     {
  810.         errno_MacSocket = invalidStreamPtr;
  811.         return (-1);
  812.     }
  813.     
  814.     if (from != NULL)
  815.     {
  816.         *fromlen = sizeof(from);
  817.         if (!theSockPtr->state & Connected)
  818.         {
  819.             if (!connect(s, from, *fromlen))
  820.             {
  821.                 return(-1);
  822.             }
  823.         }
  824.     }
  825.     return(recv(s, msg, len, flags));
  826. };
  827.  
  828. /*
  829.  *
  830.  * recvmsg - receive a message from a socket
  831.  *
  832.  */
  833. int recvmsg(int s, struct msghdr *msg, int flags)
  834. {
  835.     SockElmntPtr    theSockPtr;
  836.     
  837.     if ((theSockPtr = FindSocketStruct(s)) == NIL)
  838.     {
  839.         errno_MacSocket = invalidStreamPtr;
  840.         return (-1);
  841.     }
  842.     
  843.     if (msg->msg_name != NULL)
  844.     {
  845.         if (!theSockPtr->state & Connected)
  846.         {
  847.             if (!connect(s, (struct sockaddr_in *)msg->msg_name, msg->msg_namelen))
  848.             {
  849.                 return(-1);
  850.             }
  851.         }
  852.     }
  853.     return(recv(s, (char *)msg->msg_iov, msg->msg_iovlen, flags));
  854. };
  855.  
  856. /*
  857.  *
  858.  * send - send a message to a socket
  859.  *
  860.  */
  861. int send(int s, char *msg, int len, int flags)
  862. {
  863.     TCPiopb            *theTCPPtr;
  864.     SockElmntPtr    theSockPtr;
  865.  
  866.     struct theWDS
  867.     {
  868.         short    length;
  869.         Ptr    theDataPtr;
  870.         short    end;
  871.     } theWDS;
  872.     
  873.  
  874.     if ((theSockPtr = FindSocketStruct(s)) == NIL)
  875.     {
  876.         return (-1);
  877.     }
  878.     theTCPPtr = &(theSockPtr->thePB);
  879.     theTCPPtr->csCode = TCPSend;
  880.     theTCPPtr->csParam.send.ulpTimeoutValue = SendTimeout;
  881.     theTCPPtr->csParam.send.ulpTimeoutAction = True;
  882.     theTCPPtr->csParam.send.validityFlags = (byte)(timeoutValue | timeoutAction);
  883.     theTCPPtr->csParam.send.pushFlag = True; /* May be false ?? */
  884.     theTCPPtr->csParam.send.urgentFlag = False;
  885.     theWDS.length = len;
  886.     theWDS.theDataPtr = msg;
  887.     theWDS.end = 0;
  888.     theTCPPtr->csParam.send.wdsPtr = (Ptr)&theWDS;
  889.     theTCPPtr->csParam.send.userDataPtr = (Ptr)&theUserData;
  890.     PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
  891.     PollTCPDriver(theTCPPtr);
  892.     if (errno_MacSocket == noErr)
  893.     {
  894.         return(len);
  895.     }
  896.     else
  897.     {
  898.         return (-1);
  899.     }
  900. };
  901.  
  902. /*
  903.  *
  904.  * sendto - send a message to a socket
  905.  *
  906.  */
  907. int sendto(int s, char *msg, int len, int flags, struct sockaddr_in *to, int tolen)
  908. {
  909.     SockElmntPtr    theSockPtr;
  910.     
  911.     if ((theSockPtr = FindSocketStruct(s)) == NIL)
  912.     {
  913.         errno_MacSocket = invalidStreamPtr;
  914.         return (-1);
  915.     }
  916.     
  917.     if (to != NULL)
  918.     {
  919.         if (!theSockPtr->state & Connected)
  920.         {
  921.             if (!connect(s, to, tolen))
  922.             {
  923.                 return(-1);
  924.             }
  925.         }
  926.     }
  927.     return(send(s, msg, len, flags));
  928. };
  929.  
  930. /*
  931.  *
  932.  * sendmsg - send a message to a socket
  933.  *
  934.  */
  935. int sendmsg(int s, struct msghdr *msg, int flags)
  936. {
  937.     SockElmntPtr    theSockPtr;
  938.     
  939.     if ((theSockPtr = FindSocketStruct(s)) == NIL)
  940.     {
  941.         errno_MacSocket = invalidStreamPtr;
  942.         return (-1);
  943.     }
  944.     
  945.     if (msg->msg_name != NULL)
  946.     {
  947.         if (!theSockPtr->state & Connected)
  948.         {
  949.             if (!connect(s, (struct sockaddr_in *)msg->msg_name, msg->msg_namelen))
  950.             {
  951.                 return(-1);
  952.             }
  953.         }
  954.     }
  955.     return(send(s, (char *)msg->msg_iov, msg->msg_iovlen, flags));
  956. };
  957.  
  958.  
  959. #ifdef    MAC_APPL
  960. /*
  961.  *
  962.  * SetDialogShowTime - sets the time that an MacTCP/IP info DialogBox is vissible.
  963.  * when sec <= 0, no message will be displayed.
  964.  *
  965.  */
  966. void SetDialogShowTime(int sec)
  967. {
  968.     showTime = sec;
  969. }
  970. #endif    MAC_APPL
  971.  
  972. /*
  973.  *
  974.  * shutdown - shut down part of a full-duplex connection
  975.  *
  976.  */
  977. int shutdown(int s, int how)
  978. {
  979.     TCPiopb            *theTCPPtr;
  980.     SockElmntPtr    theSockPtr;
  981.  
  982.  
  983.     switch (how)
  984.     {
  985.     case 1: /* further sends disalowed */
  986.         return (close_MacSocket(s));
  987.         break;
  988.     case 2: /* further sends and receives disalowed */
  989.         if ((theSockPtr = FindSocketStruct(s)) == NIL)
  990.     {
  991.             return(-1);
  992.         }
  993.         theTCPPtr = &(theSockPtr->thePB);
  994.         theTCPPtr->csCode = TCPRelease;
  995.         PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
  996.         PollTCPDriver(theTCPPtr);
  997.         return (RemoveSocketStruct(s));
  998.         break;
  999.     case 0: /* further receives disalowed */
  1000.     default:
  1001.         errno_MacSocket = invalidArgument;
  1002.         return(-1);
  1003.         break;
  1004.     }
  1005. };
  1006.  
  1007. /*
  1008.  *
  1009.  * socket - create an endpoint for communication
  1010.  *
  1011.  */
  1012. int    socket(int domain, int type, int protocol)
  1013. {
  1014.     TCPiopb            *theTCPPtr;
  1015.     SockElmntPtr    theSockPtr;
  1016.     
  1017.     if (domain != AF_INET)
  1018.     {
  1019.         errno_MacSocket = nonAF_INET;
  1020.         return (-1);
  1021.     }
  1022.     if (protocol != 0)
  1023.     {
  1024.         errno_MacSocket = invalidArgument;
  1025.         return (-1);
  1026.     }
  1027.     if (type != SOCK_STREAM)
  1028.     {
  1029.         errno_MacSocket = nonSOCK_STREAM;
  1030.         return (-1);
  1031.     }
  1032.     if ((theSockPtr = (SockElmntPtr)CreateSocketStruct()) == NIL)
  1033.     {
  1034.         errno_MacSocket = noBufSpace;
  1035.         return (-1);
  1036.     }
  1037.  
  1038.     if (TCPDriverNotOpened)
  1039.     {
  1040.         if (!OpenTCPDriver())
  1041.         {
  1042.             return(-1);;
  1043.         }
  1044.     }
  1045.     theTCPPtr = &(theSockPtr->thePB);
  1046.     theTCPPtr->ioCompletion = NIL;
  1047.     theTCPPtr->ioRefNum = ioRefNumTCP;
  1048.     theTCPPtr->csCode = TCPCreate;
  1049.     theTCPPtr->csParam.create.rcvBuff = theSockPtr->sockBuf;
  1050.     theTCPPtr->csParam.create.rcvBuffLen = SockBufSize;
  1051.     theTCPPtr->csParam.create.notifyProc = SockNotify;
  1052.     theTCPPtr->csParam.create.userDataPtr = (Ptr)&theUserData;
  1053.     PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
  1054.     PollTCPDriver(theTCPPtr);
  1055.     if (errno_MacSocket == noErr)
  1056.     {
  1057.         return (theSockPtr->number);
  1058.     }
  1059.     else
  1060.     {
  1061.         RemoveSocketStruct(theSockPtr->number);
  1062.         return (-1);
  1063.     };
  1064. }
  1065.  
  1066.